package com.atguigu.lease.web.admin.service.impl;

import com.atguigu.lease.common.constant.RedisConstant;
import com.atguigu.lease.common.exception.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.common.utils.JwtUtil;
import com.atguigu.lease.model.entity.SystemUser;
import com.atguigu.lease.model.enums.BaseStatus;
import com.atguigu.lease.web.admin.service.LoginService;
import com.atguigu.lease.web.admin.service.SystemUserService;
import com.atguigu.lease.web.admin.vo.login.CaptchaVo;
import com.atguigu.lease.web.admin.vo.login.LoginVo;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import org.apache.commons.codec.digest.DigestUtils;
import org.springdoc.core.service.OperationService;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.StringRedisTemplate;

import org.springframework.stereotype.Service;


import org.springframework.util.StringUtils;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private SystemUserService systemUserService;
    @Autowired
    private OperationService operationBuilder;

    @Override
    public CaptchaVo getCaptcha() {
        //创建验证码对象
        SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4);
        //设置验证码的字符类型， TYPE_DEFAULT表示字母+数字
        specCaptcha.setCharType(Captcha.TYPE_DEFAULT);
        //获取正确的验证码并转换为小写,redis中存的是code
        String code = specCaptcha.text().toLowerCase();
        //设置redis中存储正确的验证码的key
        String key = RedisConstant.ADMIN_LOGIN_PREFIX + UUID.randomUUID();
        //获取验证码的图片信息
        String image = specCaptcha.toBase64();
        //将正确的验证码存储到redis中
        stringRedisTemplate.opsForValue().set(key, code, RedisConstant.ADMIN_LOGIN_CAPTCHA_TTL_SEC, TimeUnit.SECONDS);

        return new CaptchaVo(image, key);
    }

    @Override
    public String login(LoginVo loginVo) {
        //1、判断是否输入了验证码，验证验证码是否输入
        if (!StringUtils.hasText(loginVo.getCaptchaCode())) {
            //表示验证码未输入
            throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_NOT_FOUND);//304 未输入验证码
        }
        //2校验验证码 获取redis中正确的验证码
        String codeInRedis = stringRedisTemplate.opsForValue().get(loginVo.getCaptchaKey());
        //判断codeInRedis是否为null
        if (codeInRedis == null) {
            throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_EXPIRED); //303 验证码已过期
        }
        //若验证码不为null,则验证验证码小写
        if (!codeInRedis.equals(loginVo.getCaptchaCode().toLowerCase())) {
            throw new LeaseException(ResultCodeEnum.ADMIN_CAPTCHA_CODE_ERROR);//验证码错误
        }
        //3、验证用户是否存在
        LambdaQueryWrapper<SystemUser> wrapper = new LambdaQueryWrapper<SystemUser>();
        wrapper.eq(SystemUser::getUsername, loginVo.getUsername());
        SystemUser systemUser = systemUserService.getOne(wrapper);
        if (systemUser == null) {
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_NOT_EXIST_ERROR);//306 账号不存在
        }
        //4、校验用户是否被禁用
        if (systemUser.getStatus().equals(BaseStatus.DISABLE)) {
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_DISABLED_ERROR);//308 该用户已被禁用
        }
        //5、校验用户密码
        if (!systemUser.getPassword().equals(DigestUtils.md5Hex(loginVo.getPassword()))){
            throw new LeaseException(ResultCodeEnum.ADMIN_ACCOUNT_ERROR);//307 用户名和密码错误
        }
        //6、表示登录成功，根据userId和username创建并返回token
        return JwtUtil.createToken(systemUser.getId(), systemUser.getUsername());
    }
}












































